package com.winit.flow.manager;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.base.bean.ExecuteResult;
import com.winit.common.base.web.BaseController;
import com.winit.commons.util.HttpClientUtil;
import com.winit.commons.util.SeqGenerate;
import com.winit.config.model.Config;
import com.winit.config.service.IConfigService;
import com.winit.feature.manager.FeatureManager;
import com.winit.flow.model.*;
import com.winit.flow.repository.*;
import com.winit.flow.web.FlowController;
import com.winit.requirement.model.BrdRequirement;
import com.winit.requirement.model.ReqHistory;
import com.winit.requirement.service.IBrdRequirementService;
import com.winit.tree.model.TreeNode;
import com.winit.tree.repository.TreeRepository;
import com.winit.tree.service.IFlowFrameService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

@Component
public class FlowManager {

    private static Logger log = LoggerFactory.getLogger(FlowManager.class);
    @Autowired
    private FeatureManager featureManager;
    @Autowired
    private FlowRepository flowRepository;
    @Autowired
    private FlowRepositoryExt flowRepositoryExt;
    @Autowired
    private FlowLegendRelationRepository flowLegendRelationRepository;

    @Autowired
    private FlowReqRelationRepository flowReqRelationRepository;

    @Autowired
    private IFlowFrameService flowFrameService;
    @Autowired
    private IConfigService configService;
    @Autowired
    private FlowFeatureRelationRepository flowFeatureRelationRepository;
    @Autowired
    private IBrdRequirementService brdRequirementService;
    @Autowired
    private FlowVersionHistoryRepository versionHistoryRepository;
    @Autowired
    private TreeRepository treeRepository;

    public ExecuteResult createFlow(Flow flow) {
        ExecuteResult executeResult = null;
        executeResult = this.canFlowCreate(flow);
        if (!executeResult.success()) {
            return executeResult;
        }
        if (StringUtils.isEmpty(flow.getId())) {
            flow.setId(SeqGenerate.createId("FLO"));
        }

        String reqId = flow.getReqId();

        boolean isMaster = "-1".equals(reqId);
        String status = isMaster ? FlowStatus.ONLINE : FlowStatus.ADD;
        flow.setStatus(status);

        Map<String, Object> attrs = flow.getAttrs();

        attrs = null == attrs ? new HashMap<String, Object>() : attrs;
        attrs.put("date", System.currentTimeMillis() + "");
//        Map<String, String> kvMap = new HashMap<>();
//        for (Map.Entry<String, Object> entry : attrs.entrySet()) {
//            String key = entry.getKey();
//            Object value = entry.getValue();
//            if (null != value) {
//                if (value instanceof String) {
//                    kvMap.put(key, (String) value);
//                } else {
//                    kvMap.put(key, JSONObject.toJSONString(value));
//                }
//            }
//        }
        Map<String, Object> masterAttrs = null;
        if (isMaster) {
            masterAttrs = attrs;
        } else {
            masterAttrs = new HashMap<>();
            masterAttrs.put("date", attrs.get("date"));
        }
//        Map<String, String> kvMap = this.getDbFormatAttrs(attrs);
        Map<String, String> masterKvMap = this.getDbFormatAttrs(masterAttrs);

        this.updateVersionInfoForFlow(masterKvMap, FlowVersionGenerator.getVersionNo(), "", "");
        Config config = new Config();
        config.setKVMap(masterKvMap);
        config = this.configService.saveConfig(config);
        flow.setAttrConfigId(config.getId());
        this.flowRepository.save(flow);
        this.refreshRelationBetweenFlowAndFeature(masterAttrs, "-1", flow.getId());
        if (!isMaster) {
            executeResult = this.updateReqFlowContent(flow.getId(), attrs, reqId, "ADD");
        }
        flow.setParentId(flow.getBussinessId());
        executeResult.setData(flow);
        return executeResult;
    }

    private ExecuteResult canFlowCreate(Flow flow) {
        ExecuteResult executeResult = new ExecuteResult();
        String flowName = flow.getName();
        if (StringUtils.isEmpty(flowName)) {
            executeResult.toError("flow name不能为空");
            return executeResult;
        }
        if (null != this.flowRepository.findFirstByName(flowName)) {
            executeResult.toError("flow name重复");
        }
        if (StringUtils.isEmpty(flow.getReqId())) {
            executeResult.toError("req id不能为空");
        }
        if (StringUtils.isEmpty(flow.getBussinessId())) {
            executeResult.toError("bussiness id 不能为空");
        }
        return executeResult;
    }

    private void updateVersionInfoForFlow(Map<String, String> configMap, String version, String masterVersion, String reqSnapshot) {
        if (null != version) {
            configMap.put("version", version);
        }
        if (null != masterVersion) {
            configMap.put("master_version", masterVersion);
        }
        if (null != reqSnapshot) {
            configMap.put("req_snapshot", reqSnapshot);
        }
    }

    /**
     * @param flowId 必填
     * @param attrs  为空不作任何操作
     * @param reqId  必填且不为-1
     * @return
     * @throws Exception
     */
    public ExecuteResult updateReqFlowContent(String flowId, Map<String, Object> attrs, String reqId, String flowReqStatus) {
        ExecuteResult executeResult = new ExecuteResult();
        try {
            if (null == attrs) { //如果传过来是null则不做任何操作
                return executeResult;
            }
            if ("-1".equals(reqId)) {
                executeResult.toError("这个接口不支持req = -1的操作");
                return executeResult;
            }

            Flow dbFlow = this.flowRepository.findOne(flowId);
            if (null == dbFlow) {
                executeResult.toError("指定的flow不存在");
                return executeResult;
            }


            //处理flow与feature之间的关系
            this.refreshRelationBetweenFlowAndFeature(attrs, reqId, flowId);

            boolean reqConfigExists = false;
            String reqConfigId = null;
            FlowReqRelation flowReqRelation = this.flowReqRelationRepository.findOne(new FlowReqRelationId(flowId, reqId));
            if (null == flowReqRelation) {
                flowReqRelation = new FlowReqRelation();
                flowReqRelation.setFlowId(flowId);
                flowReqRelation.setReqId(reqId);
                flowReqRelation.setStatus(flowReqStatus);
                this.refreshBrdRequirementFlows(new String[]{flowId}, reqId, 1);
            } else {
                reqConfigId = flowReqRelation.getAttrConfigId();
                reqConfigExists = StringUtils.isEmpty(reqConfigId) ? false : true;
            }

            Config reqConfig = reqConfigExists ? this.configService.getConfigMap(reqConfigId, true) : new Config();
            Map<String, String> dbFormatAttrs = this.getDbFormatAttrs(attrs);
            if (!reqConfigExists) {  //如果对应req dbFlow config在db中不存在，那么就要初始化version等信息，否则默认为attr里一定带有这些信息
                Config masterConfig = this.configService.getConfigMap(dbFlow.getAttrConfigId(), true);
                Map<String, String> masterConfigMap = masterConfig.getKVMap();
                this.updateVersionInfoForFlow(dbFormatAttrs, FlowVersionGenerator.getVersionNo(), masterConfigMap.get("version"), masterConfigMap.get("req_snapshot"));
                dbFormatAttrs.put("from_master_version", masterConfigMap.get("version"));
            }
            dbFormatAttrs.put("date", System.currentTimeMillis() + "");
            reqConfig.setKVMap(dbFormatAttrs);
            reqConfig = this.configService.saveConfig(reqConfig);
            if (!reqConfigExists) {
                flowReqRelation.setAttrConfigId(reqConfig.getId());
                this.flowReqRelationRepository.save(flowReqRelation);
            }

            if ((!FlowStatus.UPDATE.equals(dbFlow.getStatus())) && (!FlowStatus.ADD.equals(dbFlow.getStatus()))) {
                Flow update = new Flow();
                update.setId(dbFlow.getId());
                update.setStatus(FlowStatus.UPDATE);
                this.flowRepositoryExt.updatePropertyNotNullById(update);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            executeResult.toError(e.getMessage());
        }

        return executeResult;
    }

    private void refreshBrdRequirementFlows(String[] flowIds, String reqId, int opMode) {
        List<String> reqIds = new ArrayList<>();
        reqIds.add(reqId);
        BrdRequirement brdRequirement = brdRequirementService.searchBrdRequirementsByReqIds(reqIds).get(0);
        String dbFlows = brdRequirement.getFlows();
        boolean shouldUpdate = false;
        if (-1 == opMode) {
            if (StringUtils.isEmpty(dbFlows)) {
                return;
            } else {
                List<String> dbFlowsLst = new ArrayList<>();
                dbFlowsLst.addAll(Arrays.asList(dbFlows.split(",")));
                for (String flowId : flowIds) {
                    dbFlowsLst.remove(flowId);
                }
                dbFlows = this.collectionToString(dbFlowsLst, ",");
                shouldUpdate = true;
            }
        } else if (1 == opMode) {
            if (StringUtils.isEmpty(dbFlows)) {
                dbFlows = this.collectionToString(Arrays.asList(flowIds), ",");
                shouldUpdate = true;
            } else {
                String[] dbFlowsArr = dbFlows.split(",");
                List<String> dbFlowsLst = Arrays.asList(dbFlowsArr);
                for (String flowId : flowIds) {
                    if (!dbFlowsLst.contains(flowId)) {
                        dbFlows = dbFlows + "," + flowId;
                        shouldUpdate = true;
                    }
                }
            }
        } else {
            log.error("refreshBrdRequirementFlows 不支持的opMode值:" + opMode);
        }
        if (shouldUpdate) {
            BrdRequirement update = new BrdRequirement();
            update.setReqId(reqId);
            update.setFlows(dbFlows);
            this.brdRequirementService.updateBrdById(update);
        }
    }

    private String collectionToString(Collection<String> lst, String split) {
        if (CollectionUtils.isEmpty(lst)) {
            return "";
        }
        String str = "";
        for (String temp : lst) {
            str = str + temp + ",";
        }
        return str.substring(0, str.length() - 1);
    }

    private void refreshRelationBetweenFlowAndFeature(Map<String, Object> attrs, String reqId, String flowId) {
        this.flowFeatureRelationRepository.deleteByFlowIdAndReqId(flowId, reqId);
        Object nodeData = attrs.get("nodeDataArray");
        List<FlowFeatureRelation> flowFeatureRelations = new ArrayList<>();
        if (null != nodeData) {
            List nodeDataArray = (List) nodeData;
            for (Object object : nodeDataArray) {
                Map map = (Map) object;
                String featureId = (String) map.get("feature_id");
                if (StringUtils.isEmpty(featureId)) {
                    continue;
                }
                FlowFeatureRelation featureRelation = new FlowFeatureRelation();
                featureRelation.setFlowId(flowId);
                featureRelation.setFeatureId(featureId);
                featureRelation.setReqId(reqId);
                flowFeatureRelations.add(featureRelation);
            }
        }
        if (!CollectionUtils.isEmpty(flowFeatureRelations)) {
            this.flowFeatureRelationRepository.save(flowFeatureRelations);
        }
    }

    public ExecuteResult relateWithFlow(String flowId, String reqId) {
        ExecuteResult executeResult = new ExecuteResult();
        FlowReqRelation dbFlowReqRelation = this.flowReqRelationRepository.findOne(new FlowReqRelationId(flowId, reqId));
        if (null != dbFlowReqRelation) {
            executeResult.toError("flow与req已关联");
            return executeResult;
        }
        Flow dbFlow = this.flowRepository.findOne(flowId);
        if (null == dbFlow) {
            executeResult.toError("指定flow_id的flow不存在");
            return executeResult;
        }
        try {
            Config masterConfig = this.configService.getConfigMap(dbFlow.getAttrConfigId(), true);
            executeResult = this.updateReqFlowContent(flowId, this.getObjectFormatAttrs(masterConfig.getKVMap()), reqId, "UPDATE");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            executeResult.toError(e.getMessage());
        }
        return executeResult;
    }

    public ExecuteResult dissociateWithFlow(String flowId, String reqId) {
        ExecuteResult executeResult = new ExecuteResult();
        FlowReqRelation dbFlowReqRelation = this.flowReqRelationRepository.findOne(new FlowReqRelationId(flowId, reqId));
        if (null == dbFlowReqRelation) {
            executeResult.toError("flow与req本身无关联");
            return executeResult;
        }
        Flow dbFlow = this.flowRepository.findOne(flowId);
        if (null == dbFlow) {
            executeResult.toError("指定flow_id的flow不存在");
            return executeResult;
        }
//        Config reqFlowConfig = this.configService.getConfigMap(dbFlowReqRelation.getAttrConfigId(), true);
        this.configService.deleteConfigById(dbFlowReqRelation.getAttrConfigId());
        this.refreshRelationBetweenFlowAndFeature(new HashMap<String, Object>(), reqId, flowId);
        this.flowReqRelationRepository.delete(new FlowReqRelationId(flowId, reqId));
        this.refreshBrdRequirementFlows(new String[]{flowId}, reqId, -1);

        int associateNum = this.flowRepository.computeAssociatedUnlineReq(flowId, reqId);
        if (associateNum <= 0) {
            if ((!FlowStatus.ADD.equals(dbFlow.getStatus())) && (!FlowStatus.ONLINE.equals(dbFlow.getStatus()))) {
                Flow update = new Flow();
                update.setId(dbFlow.getId());
                update.setStatus(FlowStatus.ONLINE);
                this.flowRepositoryExt.updatePropertyNotNullById(update);
            }
        }
        return executeResult;
    }

//    private void refreshFlowStatus(String flowId, String newStatus){
//        Flow dbFlow = this.flowRepository.findOne(flowId);
//        if (FlowStatus.ONLINE.equals(newStatus)){
//            if (FlowStatus.ADD.equals(dbFlow.getStatus())){
//
//            }else {
//
//            }
//        }
//    }

    private Map<String, String> getDbFormatAttrs(Map<String, Object> attrs) {
        if (null == attrs) {
            return null;
        }
        Map<String, String> kvMap = new LinkedHashMap<>();
        for (Map.Entry<String, Object> entry : attrs.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (null != value) {
                if (value instanceof String) {
                    kvMap.put(key, (String) value);
                } else {
                    kvMap.put(key, JSONObject.toJSONString(value));
                }
            }
        }
        return kvMap;
    }


    public ExecuteResult updateFlow(Flow flow) {
        ExecuteResult executeResult = new ExecuteResult();
        this.flowRepositoryExt.updatePropertyNotNullById(flow);
        executeResult.setData(flow);
        return executeResult;
    }


    public ExecuteResult deleteFlow(String flowId) {
        ExecuteResult executeResult = new ExecuteResult();
        Flow dbFlow = this.flowRepository.findOne(flowId);
        if (null == dbFlow) {
            executeResult.toError("指定flow不存在");
            return executeResult;
        }

        List<FlowReqRelation> reqRelations = this.flowReqRelationRepository.findByFlowId(flowId);
        if (!CollectionUtils.isEmpty(reqRelations)) {
            for (FlowReqRelation flowReqRelation : reqRelations) {
                if (!"-1".equals(flowReqRelation.getReqId())) {
                    this.dissociateWithFlow(flowId, flowReqRelation.getReqId());
                }
            }
        }
        //删除主版本
        this.flowRepository.delete(flowId);
        this.flowFeatureRelationRepository.deleteByFlowIdAndReqId(flowId, "-1");
        this.configService.deleteConfigById(dbFlow.getAttrConfigId());
//        this.flowLegendRelationRepository.deleteByFlowId(flowId);
        return executeResult;
    }


    public FlowController.FlowTreeNode getFlowTree(String flowFrameId, String reqId) {
        TreeNode treeNode = this.flowFrameService.getFlowFrameTree(flowFrameId);
        if (treeNode == null) {
            return null;
        }
        return this.addFlowNodeToTreeThenConvert(treeNode, reqId);
    }

    private FlowController.FlowTreeNode addFlowNodeToTreeThenConvert(TreeNode treeNode, String reqId) {

        List<TreeNode> children = treeNode.getChildren();
        FlowController.FlowTreeNode flowTreeNode = new FlowController.FlowTreeNode();
        flowTreeNode.setId(treeNode.getId());
        treeNode.setChildren(null);
        flowTreeNode.setType("1");
        flowTreeNode.setParentId(treeNode.getParentId());
        flowTreeNode.setIsDel(treeNode.getIsDel());
        flowTreeNode.setLevel(treeNode.getLevel());
        flowTreeNode.setName(treeNode.getName());
        flowTreeNode.setMetaData(treeNode);
        List<FlowController.FlowTreeNode> flowTreeNodes = new ArrayList<>();
        flowTreeNode.setChildren(flowTreeNodes);
        if (!CollectionUtils.isEmpty(children)) {
            for (TreeNode child : children) {
                flowTreeNodes.add(this.addFlowNodeToTreeThenConvert(child, reqId));
            }
        }

        List<Flow> flows = new ArrayList<Flow>();
        if (StringUtils.isEmpty(treeNode.getChildsort())) {
            flows = this.flowRepository.findByBussinessId(treeNode.getId());
        } else {
            flows = this.flowRepository.findByBussinessId(treeNode.getId(), treeNode.getChildsort());
        }

        if (!CollectionUtils.isEmpty(flows)) {
            boolean isMaster = "-1".equals(reqId);
            for (Flow flow : flows) {
                FlowController.FlowTreeNode flowNode = new FlowController.FlowTreeNode();
                flowNode.setId(flow.getId());
                flowNode.setType("2");
                flowNode.setMetaData(flow);
                flowNode.setChildren(new ArrayList<FlowController.FlowTreeNode>());
                flowNode.setParentId(treeNode.getId());
                flowNode.setLevel(StringUtils.isEmpty(treeNode.getLevel()) ? "0" : ((Integer.valueOf(treeNode.getLevel()).intValue() + 1) + ""));
                flowNode.setIsDel("1");
                flowNode.setName(flow.getName());
                if (isMaster) {
                    flowNode.setStatus(flow.getStatus());
                } else {
                    FlowReqRelation flowReqRelation = this.flowReqRelationRepository.findByFlowIdAndReqId(flow.getId(), reqId);
                    if (null == flowReqRelation) {
                        flowNode.setStatus(flow.getStatus());
                    } else {
                        flowNode.setStatus(flowReqRelation.getStatus());
                    }
                }
                flowTreeNodes.add(flowNode);
            }
        }
        return flowTreeNode;
    }


    public FlowController.FlowTreeNode getFlowTreeNode(String flowId) {
        Flow flow = this.flowRepository.findOne(flowId);
        FlowController.FlowTreeNode flowNode = new FlowController.FlowTreeNode();
        if (null != flow) {
            flowNode.setId(flow.getId());
            flowNode.setType("2");
            flowNode.setMetaData(flow);
            flowNode.setChildren(new ArrayList<FlowController.FlowTreeNode>());
            flowNode.setParentId(flow.getBussinessId());
            flowNode.setIsDel("1");
            flowNode.setName(flow.getName());
            flowNode.setStatus(flow.getStatus());
            TreeNode treeNode = treeRepository.findOne(flow.getBussinessId());
            flowNode.setLevel(StringUtils.isEmpty(treeNode.getLevel()) ? "0" : ((Integer.valueOf(treeNode.getLevel()).intValue() + 1) + ""));
        }
        return flowNode;
    }

    public Flow getFlowById(String flowId) {
        return this.flowRepository.findOne(flowId);
    }


    public ExecuteResult updateFlowLegends(String flowId, String reqId, Map<String, Object> attrs) {
        ExecuteResult executeResult = new ExecuteResult();
        if (!"-1".equals(reqId)) {
            executeResult.toError("这个接口暂时不支持req != -1的操作");
            return executeResult;
        }
        Flow flow = this.flowRepository.findOne(flowId);
        boolean configExists = false;
        if (null == flow) {
            executeResult.toError("指定的flow不存在");
            return executeResult;
        }
        String attrConfigId = flow.getAttrConfigId();
        Config existsConfig = null;
        if (!StringUtils.isEmpty(attrConfigId)) {
            configExists = true;
            try {
                existsConfig = this.configService.getConfigMap(attrConfigId, true);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                executeResult.toError(e.getMessage());
                return executeResult;
            }
        }
        if (null == existsConfig) {
            configExists = false;
            existsConfig = new Config();
        }
        Map<String, String> kvMap = new HashMap<>();
        if (attrs.size() > 0) {
            for (Map.Entry<String, Object> entry : attrs.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (null != value) {
                    if (value instanceof String) {
                        kvMap.put(key, (String) value);
                    } else {
                        kvMap.put(key, JSONObject.toJSONString(value));
                    }
                }
            }
        }
        kvMap.put("date", System.currentTimeMillis() + "");
        existsConfig.setKVMap(kvMap);
        Config newConfig = this.configService.saveConfig(existsConfig, false);
        if (!configExists) {
            Flow update = new Flow();
            update.setId(flowId);
            update.setAttrConfigId(newConfig.getId());
            this.flowRepositoryExt.updatePropertyNotNullById(update);
        }
        this.flowLegendRelationRepository.deleteByFlowId(flowId);
        List<FlowLegendRelation> flowLegendRelations = new ArrayList<>();
        Object nodeData = attrs.get("nodeDataArray");
        if (null != nodeData) {
            List nodeDataArray = (List) nodeData;
            for (Object object : nodeDataArray) {
                Map map = (Map) object;
                String legend_id = (String) map.get("legend_id");
                if (StringUtils.isEmpty(legend_id)) {
                    continue;
                }
                FlowLegendRelation flowLegendRelation = new FlowLegendRelation();
                flowLegendRelation.setFlowId(flowId);
                flowLegendRelation.setLegendId(legend_id);
                flowLegendRelation.setReqId(reqId);
                flowLegendRelations.add(flowLegendRelation);
            }
        }
        if (!CollectionUtils.isEmpty(flowLegendRelations)) {
            this.flowLegendRelationRepository.save(flowLegendRelations);
        }
        return executeResult;
    }


    public Flow getFlowDetail(String flowId, String reqId) throws Exception {
        Flow flow = this.flowRepository.findOne(flowId);
        if (flow == null) {
            return null;
        }
        //前端要求 20180308
        if (flow.getBussinessId() != null) {
            TreeNode treeNode = this.flowFrameService.getFlowFrameTree(flow.getBussinessId());
            flow.setFrameName(treeNode.getName());
        }
        if (!"-1".equals(reqId)) {
            FlowReqRelation flowReqRelation = this.flowReqRelationRepository.findByFlowIdAndReqId(flowId, reqId);
            if (null != flowReqRelation) {
                flow.setStatus(flowReqRelation.getStatus());
            }
        }
        String attrConfigId = null;
        if ("-1".equals(reqId)) {
            attrConfigId = flow.getAttrConfigId();
        } else {
            FlowReqRelation flowReqRelation = this.flowReqRelationRepository.findOne(new FlowReqRelationId(flowId, reqId));
            if (null != flowReqRelation) {
                attrConfigId = flowReqRelation.getAttrConfigId();
            }
//            else {
//                attrConfigId = flow.getAttrConfigId();
//            }
        }
        if (!StringUtils.isEmpty(attrConfigId)) {
            Config config = null;
            try {
                config = this.configService.getConfigMap(attrConfigId, true);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return null;
            }
            if (null != config) {
                Map<String, String> kvmap = config.getKVMap();
                Map<String, Object> attrs = this.getObjectFormatAttrs(kvmap);
                if (attrs.containsKey("nodeDataArray")) {
                    JSONArray array = (JSONArray) attrs.get("nodeDataArray");
                    for (int i = 0; i < array.size(); i++) {
                        JSONObject object = array.getJSONObject(i);
                        if (object.containsKey("feature_id") && !StringUtils.isEmpty(object.getString("feature_id"))) {

                            ExecuteResult executeResult = this.featureManager.getFeature(object.getString("feature_id"), null, reqId, null, "0", "1");
                            if ("0".equals(executeResult.getCode()) && null != executeResult.getData() && ((List) executeResult.getData()).size() > 0) {
                                object.put("feature_info", ((List) executeResult.getData()).get(0));
                            }
                        }
                        if (object.containsKey("flow_id") && !StringUtils.isEmpty(object.getString("flow_id"))) {
                            //查询flow信息,不包括attr详情
                            List<Flow> flows = getReqFlows(reqId, "1", object.getString("flow_id"));
                            if (null != flows) {
                                object.put("flow_info", flows.get(0));
                            }
                        }
                    }
                }

                flow.setAttrs(attrs);
            }
        }
        return flow;
    }

    private Map<String, Object> getObjectFormatAttrs(Map<String, String> attrs) {
        if (null == attrs) {
            return null;
        }
        Map<String, Object> objectAttrs = new LinkedHashMap<>();

        for (Map.Entry<String, String> entry : attrs.entrySet()) {
            if ("date".equalsIgnoreCase(entry.getKey())) {
                objectAttrs.put("date", entry.getValue());
                continue;
            }
            try {
                if ("nodeDataArray".equalsIgnoreCase(entry.getKey())) {
                    JSONArray array = JSONObject.parseArray(entry.getValue());
                    objectAttrs.put(entry.getKey(), array);
                } else {
                    objectAttrs.put(entry.getKey(), JSONObject.parseArray(entry.getValue()));
                }
            } catch (JSONException jsonException) {
                try {
                    objectAttrs.put(entry.getKey(), JSONObject.parse(entry.getValue()));
                } catch (JSONException jsonException1) {
                    log.info(" 解析flow attr时，" + entry.getKey() + " 对应的value是一个字符串");
                    objectAttrs.put(entry.getKey(), entry.getValue());
                }
            }
        }

        return objectAttrs;
    }

    public List<Flow> getReqFlows(String reqId) {
        return getReqFlows(reqId, "1");
    }

    public List<Flow> getReqFlows(String reqId, String withAttr) {
        return getReqFlows(reqId, withAttr, null);
    }

    public List<Flow> getReqFlows(String reqId, String withAttr, String flowid) {
        List<String> reqIds = new ArrayList<>();
        reqIds.add(reqId);
        List<BrdRequirement> requirements = this.brdRequirementService.searchBrdRequirementsByReqIds(reqIds);
        if (CollectionUtils.isEmpty(requirements)) {
            return null;
        }
        BrdRequirement dbBrdRequirement = requirements.get(0);
        String flows = dbBrdRequirement.getFlows();
        if (StringUtils.isEmpty(flows)) {
            return null;
        }
        String[] flowIdsArr = null;
        if (StringUtils.isEmpty(flowid)) {
            flowIdsArr = flows.split(",");
        } else {
            flowIdsArr = flowid.split(",");
        }

        List<Flow> temp = this.flowRepository.findByIdIn(flowIdsArr);
        if (CollectionUtils.isEmpty(temp)) {
            return null;
        }
        List<Flow> result = new ArrayList<>();
        Map<String, Flow> container = new HashMap<>();
        for (Flow flow : temp) {
            container.put(flow.getId(), flow);
        }
        Flow tempFlow = null;
        for (String flowId : flowIdsArr) {
            tempFlow = container.remove(flowId);
            if (null != tempFlow) {
                if ("0".equalsIgnoreCase(withAttr)) {
                    try {
                        tempFlow = getFlowDetail(flowId, reqId);
                    } catch (Exception e) {
                    }
                } else {
                    FlowReqRelation relation = this.flowReqRelationRepository.findByFlowIdAndReqId(flowId, reqId);
                    if (null != relation) {
                        tempFlow.setStatus(relation.getStatus());
                    }
                }
                result.add(tempFlow);
            }
        }
        return result;
    }

    public ExecuteResult updateMasterFlow(Flow flow) {
        //TODO  修改生成新版本
        ExecuteResult executeResult = new ExecuteResult();
        try {
            Flow dbFlow = this.flowRepository.findOne(flow.getId());
            if (null == dbFlow) {
                executeResult.toError("指定的flow不存在");
                return executeResult;
            }
            this.flowRepositoryExt.updatePropertyNotNullById(flow);
            Map<String, Object> attrs = flow.getAttrs();
            if (null == attrs) {
                return executeResult;
            }

            this.backupFlow("-1", flow.getId(), VersionHistoryType.MASTER_FLOW, null);


            String attrConfigId = dbFlow.getAttrConfigId();
            attrs.put("date", System.currentTimeMillis() + "");
            attrs.put("version", FlowVersionGenerator.getVersionNo());
            Config dbConfig = this.configService.getConfigMap(attrConfigId, true);
            Map<String, String> dbFormatAttrs = this.getDbFormatAttrs(attrs);
            dbConfig.setKVMap(dbFormatAttrs);
            this.configService.saveConfig(dbConfig);
            this.refreshRelationBetweenFlowAndFeature(attrs, "-1", flow.getId());


        } catch (Exception e) {
            log.error(e.getMessage(), e);
            executeResult.toError(e.getMessage());
        }
        executeResult.setData(flow);
        return executeResult;
    }

    public ExecuteResult operateForReqOnline(List<String> reqIds) {
        ExecuteResult executeResult = null;
        for (String reqId : reqIds) {
            try {
                executeResult = this.operateForReqOnline(reqId);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                executeResult.toError(e.getMessage());
                return executeResult;
            }
            if (!executeResult.success()) {
                return executeResult;
            }
        }
        return executeResult;
    }

    public ExecuteResult operateForReqOnline(String reqId) throws Exception {
        List<FlowReqRelation> flowReqRelations = this.flowReqRelationRepository.findByReqId(reqId);
        if (CollectionUtils.isEmpty(flowReqRelations)) {
            return new ExecuteResult();
        }
        ExecuteResult executeResult = null;
        for (FlowReqRelation flowReqRelation : flowReqRelations) {
            if ("ONLINE".equalsIgnoreCase(flowReqRelation.getStatus())) {
                continue;
            }
            executeResult = this.operateForReqOnline(flowReqRelation);
            if (!executeResult.success()) {
                return executeResult;
            }
        }

        return executeResult;
    }

    public ExecuteResult operateForReqOnline(FlowReqRelation flowReqRelation) throws Exception {
        ExecuteResult executeResult = new ExecuteResult();

        String reqId = flowReqRelation.getReqId();
        String flowId = flowReqRelation.getFlowId();
        Flow dbFlow = this.flowRepository.findOne(flowId);
        /** 判断版本冲突 */
        Config masterConfig = this.configService.getConfigMap(dbFlow.getAttrConfigId(), false);
        Map<String, String> masterConfigMap = masterConfig.getKVMap();
        String masterVersion = masterConfigMap.get("version");
        Config reqConfig = this.configService.getConfigMap(flowReqRelation.getAttrConfigId(), false);
        Map<String, String> reqConfigMap = reqConfig.getKVMap();
        String reqRefMasterVersion = reqConfigMap.get("master_version");
        if ((masterVersion != null) && (!masterVersion.equals(reqRefMasterVersion))) {   //版本冲突
            executeResult.setCode(BaseController.REQUEST_ERROR);
            executeResult.setDesc("flow config版本冲突,feature_name:" + dbFlow.getName() + ",master_version:" + masterVersion + ", req_ref_master_version:" + reqRefMasterVersion + ", req_snapshot of master:" + masterConfigMap.get("req_snapshot"));
            return executeResult;
        }
        /* 合并feature上线上时持feature历史版本记录，2018-01-10 */
        this.backupFlow(reqId, flowId, VersionHistoryType.MASTER_FLOW, null);

//        String flowConfigId = flowReqRelation.getAttrConfigId();

//        this.configService.mergeConfigById(featureConfigId, feature.getAttrConfigId(), true);
//            Indexing reqFeatureIndexing = this.indexingService.getIndexing(new IndexingId("req_feature_indexing", reqId));
        /**更新version信息*/
//        masterConfig = this.configService.getConfigMap(dbFlow.getAttrConfigId(), false);
        masterConfigMap = new LinkedHashMap<>();
        masterConfigMap.putAll(reqConfig.getKVMap());
        String newMasterVersion = FlowVersionGenerator.getVersionNo();
        this.updateVersionInfoForFlow(masterConfigMap, newMasterVersion, "", reqId);
        String time = System.currentTimeMillis() + "";
        masterConfigMap.put("date", time);

        Map<String, Object> masterObjectFormatAttrs = this.getObjectFormatAttrs(masterConfigMap);
        Object nodeDataObject = masterObjectFormatAttrs.get("nodeDataArray");
        if (null != nodeDataObject) {
            JSONArray array = (JSONArray) nodeDataObject;
            for (int i = 0; i < array.size(); i++) {
                JSONObject object = array.getJSONObject(i);
                object.remove("nodeStatus");
                object.put("status", "ONLINE");
            }
            masterConfigMap = this.getDbFormatAttrs(masterObjectFormatAttrs);
        }

        this.refreshRelationBetweenFlowAndFeature(masterObjectFormatAttrs, "-1", flowId);


        masterConfig.setKVMap(masterConfigMap);
        this.configService.saveConfig(masterConfig);
        this.updateVersionInfoForFlow(reqConfigMap, null, newMasterVersion, reqId);
        reqConfigMap.put("to_master_version", newMasterVersion);
        reqConfigMap.put("date", time);
        this.configService.saveConfig(reqConfig);

        this.backupFlow(reqId, flowId, VersionHistoryType.REQ_FLOW, null);

        //        this.indexingService.deleteIndex(new IndexingId("feature_req_indexing", id));
        String dbFlowStatus = dbFlow.getStatus();
        if (!FlowStatus.ONLINE.equals(dbFlowStatus)) {
            Flow update = new Flow();
            update.setId(flowId);
            int num = this.flowRepository.computeAssociatedUnlineReq(flowId, reqId);
            if (num > 0) {
                update.setStatus(FlowStatus.UPDATE);
            } else {
                update.setStatus(FlowStatus.ONLINE);
            }
            this.flowRepositoryExt.updatePropertyNotNullById(update);
        }


        this.flowReqRelationRepository.updateFlowStatusByReqIdAndFlowId(FlowRelationStatus.ONLINE, flowId, reqId, null);
        return executeResult;
    }

    private void backupFlow(String reqId, String flowId, String versionHistoryType, String newHistoryVersion) throws Exception {
        Flow dbFlow = this.flowRepository.findOne(flowId);
        Config configBackup = null;

        if (VersionHistoryType.MASTER_FLOW.equalsIgnoreCase(versionHistoryType)) {  //是否生成master_flow
            configBackup = this.configService.getConfigMap(dbFlow.getAttrConfigId(), false);
            if (newHistoryVersion == null) {
                newHistoryVersion = this.getFlowVersionForMaster(flowId, versionHistoryType);
//                this.getFlowVersionForReq()
            }
        } else {
            FlowReqRelation flowReqRelation = this.flowReqRelationRepository.findOne(new FlowReqRelationId(flowId, reqId));
            if (null == flowReqRelation) {
                return;
            }
            configBackup = this.configService.getConfigMap(flowReqRelation.getAttrConfigId(), true);
            if (newHistoryVersion == null) {
                newHistoryVersion = this.getFlowVersionForReq(reqId, flowId, versionHistoryType);
            }
        }
        if (configBackup.getKVMap().get("date") == null) {
            configBackup.getKVMap().put("date", System.currentTimeMillis() + "");
            this.configService.saveConfig(configBackup);
        }
        String reqName = null;
        if ("-1".equals(reqId)) {        //是谁操作的
            reqName = "MASTER";

        } else {
            BrdRequirement brdRequirement = this.brdRequirementService.getBrdRequirementByReqId(reqId);
            reqName = brdRequirement.getReqName();

        }
        configBackup.setId(null);
        configBackup = this.configService.saveConfig(configBackup);
        VersionHistory versionHistory = new VersionHistory();
        versionHistory.setAttrConfigId(configBackup.getId());
        versionHistory.setCreateTime(new Date());
        versionHistory.setRelationId(flowId);
        versionHistory.setReqId(reqId);
        versionHistory.setRelationName(dbFlow.getName());
        versionHistory.setVersion(newHistoryVersion);
        versionHistory.setReqName(reqName);
        versionHistory.setType(versionHistoryType);
        this.versionHistoryRepository.save(versionHistory);
    }


    private String getFlowVersionForMaster(String flowId, String versionHistoryType) {
        VersionHistory versionHistory = this.versionHistoryRepository.findLatestVersionByRelationIdAndType(flowId, versionHistoryType);
        if (null == versionHistory) {
            return "V1.0";
        }
        String curVersion = versionHistory.getVersion();
        int splitLoc = curVersion.indexOf(".");
        String prefix = curVersion.substring(0, splitLoc);
        String suffix = curVersion.substring(splitLoc + 1);
        suffix = (Integer.valueOf(suffix) + 1) + "";
        return prefix + "." + suffix;
    }

    public ExecuteResult updateSequenceOfReqFlow(String reqId, List<String> flowIds) {
        BrdRequirement update = new BrdRequirement();
        update.setReqId(reqId);
        String flows = this.collectionToString(flowIds, ",");
        update.setFlows(flows);
        this.brdRequirementService.updateBrdById(update);
        return new ExecuteResult();
    }


    public ExecuteResult getFlowFeatures(String flowId, String reqId) {
        ExecuteResult executeResult = new ExecuteResult();
        List result = new ArrayList();
        executeResult.setData(result);
        List<FlowFeatureRelation> flowFeatureRelations = this.flowFeatureRelationRepository.findByFlowIdAndReqId(flowId, reqId);
        if (CollectionUtils.isEmpty(flowFeatureRelations)) {
            return executeResult;
        }
        try {
            for (FlowFeatureRelation flowFeatureRelation : flowFeatureRelations) {

                ExecuteResult featureR = this.featureManager.getFeature(flowFeatureRelation.getFeatureId(), null, reqId, null, "0", "1");
                if ("0".equals(featureR.getCode())) {
                    Object data = featureR.getData();
                    if (null != data && ((List) data).size() > 0) {
                        result.add(((List) data).get(0));
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            executeResult.toError(e.getMessage());
        }
        return executeResult;
    }


    public ExecuteResult operateForFeatureModify(String reqId, String featureId) {
        ExecuteResult executeResult = new ExecuteResult();
        List<FlowFeatureRelation> flowFeatureRelations = this.flowFeatureRelationRepository.findByFeatureIdAndReqId(featureId, "-1");
        if (CollectionUtils.isEmpty(flowFeatureRelations)) {
            return executeResult;
        }
        for (FlowFeatureRelation flowFeatureRelation : flowFeatureRelations) {
            if (flowFeatureRelation.getReqId().equals(reqId)) {
                continue;
            }
            String flowId = flowFeatureRelation.getFlowId();
            FlowReqRelation flowReqRelation = this.flowReqRelationRepository.findByFlowIdAndReqId(flowId, reqId);
            if (null != flowReqRelation) {
                continue;
            }
            try {
                Flow dbFlow = this.flowRepository.findOne(flowId);
                Config masterConfig = this.configService.getConfigMap(dbFlow.getAttrConfigId(), true);
                executeResult = this.updateReqFlowContent(flowId, this.getObjectFormatAttrs(masterConfig.getKVMap()), reqId, "NODE_UPDATE");
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                executeResult.toError(e.getMessage());
                return executeResult;
            }
        }
        return executeResult;
    }

    public ExecuteResult reqSubmit(String reqId, String version) {
        ExecuteResult executeResult = new ExecuteResult();
        List<FlowReqRelation> flowReqRelations = this.flowReqRelationRepository.findByReqId(reqId);
        if (CollectionUtils.isEmpty(flowReqRelations)) {
            return executeResult;
        }
        try {
            for (FlowReqRelation flowReqRelation : flowReqRelations) {
                this.submit(flowReqRelation.getFlowId(), reqId, version);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            executeResult.toError(e.getMessage());
        }
        return executeResult;
    }

    public void submit(String flowId, String reqId, String version) throws Exception {
        this.backupFlow(reqId, flowId, VersionHistoryType.REQ_FLOW, version);
//        FlowReqRelation flowReqRelation = this.flowReqRelationRepository.findByFlowIdAndReqId(flowId, reqId);
//        Config reqConfig = this.configService.getConfigMap(flowReqRelation.getAttrConfigId(), true);
//        if (reqConfig.getKVMap().get("date") == null){
//            reqConfig.getKVMap().put("date", System.currentTimeMillis() + "");
//            this.configService.saveConfig(reqConfig);
//        }
//        VersionHistory versionHistory = new VersionHistory();
//        BrdRequirement brdRequirement = this.brdRequirementService.getBrdRequirementByReqId(reqId);
//        versionHistory.setReqName(brdRequirement.getReqName());
//        versionHistory.setReqId(reqId);
//        versionHistory.setType(VersionHistoryType.REQ_FLOW);
//        Flow dbFlow = this.flowRepository.findOne(flowId);
//        versionHistory.setRelationName(dbFlow.getName());
//        versionHistory.setRelationId(flowId);
//        versionHistory.setCreateTime(new Date());
//        if (StringUtils.isEmpty(version)){
//            version = this.getFlowVersionForReq(reqId, flowId, VersionHistoryType.REQ_FEATURE);
//        }
//        versionHistory.setVersion(version);
//        reqConfig.setId(null);
//        reqConfig = this.configService.saveConfig(reqConfig);
//        versionHistory.setAttrConfigId(reqConfig.getId());
//        this.configService.saveConfig(reqConfig);
//        this.versionHistoryRepository.save(versionHistory);

    }


    private String getFlowVersionForReq(String reqId, String flowId, String versionHistoryType) {
        VersionHistory versionHistory = this.versionHistoryRepository.findLatestVersionByRelationIdAndReqIdAndType(flowId, reqId, versionHistoryType);
        if (null == versionHistory) {
            return "v1.1.1";
        }
        String oldVersion = versionHistory.getVersion();
        if (StringUtils.isEmpty(oldVersion)) {
            return "v1.1.1";
        }
        String version = "v";
        oldVersion = oldVersion.substring(1);
        oldVersion = oldVersion.replaceAll("\\.", "");
        Integer intVersion = Integer.valueOf(oldVersion) + 1;
        for (char ch : intVersion.toString().toCharArray()) {
            version = version + ch + ".";
        }
        version = version.substring(0, version.length() - 1);
        return version;
    }


    public Map<String, Object> getSubmitHistory(String featureId, String reqId) {
        //TODO 根据版本记录查询
        Map<String, Object> rs = new LinkedHashMap<>();
        if (!StringUtils.isEmpty(reqId)) {
            rs.put(reqId, this.getVersionHistories(featureId, reqId));
            return rs;
        }
        //到这里查询所有未上线的req的submit history

//        Map<String, String> indexMap = featureReqIndexing.getIndexMap();
//        for (Map.Entry<String, String> entry : indexMap.entrySet()){
//            String req = entry.getKey();
//            rs.put(req, this.getVersionHistories(featureId, req));
//        }
        return rs;
    }

    private List<VersionHistory> getVersionHistories(String featureId, String reqId) {
        List<VersionHistory> versionHistories = this.versionHistoryRepository.findByReqIdAndRelationIdAndType(reqId, featureId, VersionHistoryType.REQ_FLOW);
        //兼容前端null报错问题
        versionHistories = null == versionHistories ? new ArrayList<VersionHistory>() : versionHistories;
        return versionHistories;
    }


    public int getFlowNumOfFeature(String featureId, String reqId) {
        if (StringUtils.isEmpty(reqId)) {
            reqId = "-1";
        }
        return this.flowFeatureRelationRepository.countByFeatureIdAndReqId(featureId, reqId);
    }

    public List<Flow> getFlowsOfFeature(String featureId, String reqId) {

        if (StringUtils.isEmpty(reqId)) {
            reqId = "-1";
        }
        List<FlowFeatureRelation> flowFeatureRelations = this.flowFeatureRelationRepository.findByFeatureIdAndReqId(featureId, reqId);
        if (CollectionUtils.isEmpty(flowFeatureRelations)) {
            return new ArrayList<>();
        }
        List<String> flowIds = new ArrayList<>();
        for (FlowFeatureRelation flowFeatureRelation : flowFeatureRelations) {
            flowIds.add(flowFeatureRelation.getFlowId());
        }
        List<Flow> flows = new ArrayList<>();
        Iterable<Flow> iterable = this.flowRepository.findAll(flowIds);
        if (null != iterable) {
            Iterator<Flow> iterator = iterable.iterator();
            while (iterator.hasNext()) {
                flows.add(iterator.next());
            }
        }
        return flows;
    }

    public ExecuteResult getAllElements() {
        ExecuteResult executeResult = new ExecuteResult();
        Map<String, List> rs = new HashMap<>();
        List<TreeNode> frames = this.flowFrameService.getAllFlowFrame();
        rs.put("frames", frames);
        List<Flow> flows = new LinkedList<>();
        rs.put("flows", flows);
        Iterable<Flow> iterable = this.flowRepository.findAll();
        if (null != iterable) {
            for (Flow flow : iterable) {
                flow.setParentId(flow.getBussinessId());
                flows.add(flow);
            }
        }
        executeResult.setData(rs);
        return executeResult;
    }


    public Map<String, Object> getAllFlowVersions(String flowId) throws Exception {
        Map<String, Object> rs = new HashMap<>();
        List<FlowController.FlowVersionVo> masterVersion = new ArrayList<>();
        List<FlowController.FlowVersionVo> reqVersion = new ArrayList<>();
        rs.put("master", masterVersion);
        rs.put("req", reqVersion);
        Flow dbFlow = this.flowRepository.findOne(flowId);
        if (null == dbFlow) {
            return rs;
        }
        /** 获取master的版本 */
        List<VersionHistory> masterVersionHistories = this.versionHistoryRepository.findByRelationIdAndType(flowId, VersionHistoryType.MASTER_FLOW);
        if (!CollectionUtils.isEmpty(masterVersionHistories)) {
            for (VersionHistory versionHistory : masterVersionHistories) {
                FlowController.FlowVersionVo flowVersionVo = new FlowController.FlowVersionVo();
                masterVersion.add(flowVersionVo);
                flowVersionVo.setFlowId(flowId);
                flowVersionVo.setReqId("-1");
                flowVersionVo.setReqName("master");
                flowVersionVo.setVersion(versionHistory.getVersion());
                Config masterVersionConfig = this.configService.getConfigMap(versionHistory.getAttrConfigId(), true);
                flowVersionVo.setAttrs(this.getObjectFormatAttrs(masterVersionConfig.getKVMap()));
            }
        }

        /** 获取master online */
        FlowController.FlowVersionVo masterOnlineFlowVersionVo = new FlowController.FlowVersionVo();
        masterVersion.add(masterOnlineFlowVersionVo);
        masterOnlineFlowVersionVo.setFlowId(flowId);
        masterOnlineFlowVersionVo.setVersion("online");
        masterOnlineFlowVersionVo.setReqId("-1");
        masterOnlineFlowVersionVo.setReqName("master");
        Config masterOnlineConfig = this.configService.getConfigMap(dbFlow.getAttrConfigId(), true);
        masterOnlineFlowVersionVo.setAttrs(this.getObjectFormatAttrs(masterOnlineConfig.getKVMap()));

        /** 获取req submit */
        List<VersionHistory> reqVersionHistories = this.versionHistoryRepository.findByRelationIdAndType(flowId, VersionHistoryType.REQ_FLOW);
        if (!CollectionUtils.isEmpty(reqVersionHistories)) {
            for (VersionHistory versionHistory : reqVersionHistories) {
                FlowController.FlowVersionVo flowVersionVo = new FlowController.FlowVersionVo();
                reqVersion.add(flowVersionVo);
                flowVersionVo.setFlowId(flowId);
                flowVersionVo.setReqId(versionHistory.getReqId());
                flowVersionVo.setReqName(versionHistory.getReqName());
                flowVersionVo.setVersion(versionHistory.getVersion());
                Config masterVersionConfig = this.configService.getConfigMap(versionHistory.getAttrConfigId(), true);
                flowVersionVo.setAttrs(this.getObjectFormatAttrs(masterVersionConfig.getKVMap()));
            }
        }

        /** 获取req temp */
        List<FlowReqRelation> tempFlowReqRelations = this.flowReqRelationRepository.findByFlowIdAndStatusNot(flowId, "ONLINE");
        if (!CollectionUtils.isEmpty(tempFlowReqRelations)) {
            for (FlowReqRelation flowReqRelation : tempFlowReqRelations) {
                FlowController.FlowVersionVo flowVersionVo = new FlowController.FlowVersionVo();
                reqVersion.add(flowVersionVo);
                flowVersionVo.setFlowId(flowId);
                flowVersionVo.setReqId(flowReqRelation.getReqId());
                BrdRequirement brdRequirement = this.brdRequirementService.getBrdRequirementByReqId(flowReqRelation.getReqId());
                if (null != brdRequirement) {
                    flowVersionVo.setReqName(brdRequirement.getReqName());
                }
                flowVersionVo.setVersion("temp");
                Config reqVersionConfig = this.configService.getConfigMap(flowReqRelation.getAttrConfigId(), true);
                flowVersionVo.setAttrs(this.getObjectFormatAttrs(reqVersionConfig.getKVMap()));
            }
        }
        return rs;
    }


    public ExecuteResult getLatestSubmitFlow(String flowId, String reqId) {
        ExecuteResult executeResult = new ExecuteResult();

        try {
            executeResult.setData(this.getLatestSubmitFlowById(reqId, flowId));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            executeResult.setCode(BaseController.REQUEST_ERROR);
            executeResult.setDesc("查询config出错");
            return executeResult;
        }
        return executeResult;
    }

    private Flow getLatestSubmitFlowById(String reqId, String flowId) throws Exception {
        VersionHistory topVersionHistory = this.versionHistoryRepository.findFirstByTypeAndReqIdAndRelationIdOrderByCreateTimeDesc(VersionHistoryType.REQ_FLOW, reqId, flowId);
        if (null == topVersionHistory) {
            return null;
        }
        Flow dbFlow = this.flowRepository.findOne(flowId);
        if (null == dbFlow) {
            return null;
        }
        Config config = this.configService.getConfigMap(topVersionHistory.getAttrConfigId(), true);
        dbFlow.setAttrs(this.getObjectFormatAttrs(config.getKVMap()));
        return dbFlow;
    }

    public List<Flow> getReqLatestSubmitFlows(String reqId) throws Exception {
        List<Flow> latestFlows = new ArrayList<>();
        ReqHistory reqHistory = this.brdRequirementService.getLatestSubmitHistory(reqId);
        if (null == reqHistory) {
            return latestFlows;
        }
        String flows = reqHistory.getFlows();
        if (StringUtils.isEmpty(flows)) {
            return latestFlows;
        }
        Flow temp;
        for (String flowIdStr : flows.split(",")) {
            temp = this.getLatestSubmitFlowById(reqId, flowIdStr);
            if (null != temp) {
                latestFlows.add(temp);
            }
        }
        return latestFlows;
    }
}
